<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Agent Descriptions JSON-LD 文件链接图</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
    <style>
        #network-container {
            height: 80vh;
            border: 1px solid #ddd;
            background-color: #fafafa;
            border-radius: 8px;
        }

        .node-tooltip {
            position: absolute;
            padding: 8px;
            background: white;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 12px;
            pointer-events: none;
            z-index: 1000;
        }
    </style>
</head>
<body class="bg-gray-50">
    <div class="container mx-auto px-4 py-8">
        <nav class="mb-8">
            <button onclick="window.location.href='/'" 
                    class="text-gray-600 hover:text-gray-900 flex items-center">
                <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
                </svg>
                关闭
            </button>
        </nav>

        <div class="bg-white rounded-lg shadow-lg p-6">
            <div id="network-container"></div>
        </div>
    </div>

    <script>
        let network = null;
        let nodes = new vis.DataSet();
        let edges = new vis.DataSet();
        let processedUrls = new Set();
        let currentLevel = 0;
        const MAX_LEVEL = 5;

        // 网络图配置
        const networkOptions = {
            nodes: {
                shape: 'box',
                margin: 10,
                font: {
                    size: 14
                },
                shadow: true
            },
            edges: {
                arrows: 'to',
                smooth: {
                    type: 'cubicBezier',
                    forceDirection: 'horizontal'
                }
            },
            layout: {
                hierarchical: {
                    direction: 'LR',
                    sortMethod: 'directed',
                    levelSeparation: 200,
                    nodeSpacing: 150
                }
            },
            physics: false,
            interaction: {
                hover: true,
                tooltipDelay: 200
            }
        };

        // 初始化网络图
        function initNetwork() {
            const container = document.getElementById('network-container');
            const data = {
                nodes: nodes,
                edges: edges
            };
            network = new vis.Network(container, data, networkOptions);

            // 添加点击事件
            network.on('click', function(params) {
                if (params.nodes.length > 0) {
                    const nodeId = params.nodes[0];
                    const node = nodes.get(nodeId);
                    if (node.url) {
                        handleUrlClick(node.url);
                    }
                }
            });

            // 添加悬停提示
            network.on('hoverNode', function(params) {
                const node = nodes.get(params.node);
                showTooltip(node.url, params.event.pageX, params.event.pageY);
            });

            network.on('blurNode', function() {
                hideTooltip();
            });
        }

        function showTooltip(text, x, y) {
            let tooltip = document.querySelector('.node-tooltip');
            if (!tooltip) {
                tooltip = document.createElement('div');
                tooltip.className = 'node-tooltip';
                document.body.appendChild(tooltip);
            }
            tooltip.textContent = text;
            tooltip.style.left = (x + 10) + 'px';
            tooltip.style.top = (y + 10) + 'px';
            tooltip.style.display = 'block';
        }

        function hideTooltip() {
            const tooltip = document.querySelector('.node-tooltip');
            if (tooltip) {
                tooltip.style.display = 'none';
            }
        }

        function handleUrlClick(url) {
            const urlType = getUrlType(url);
            if (urlType === 'json') {
                // Get base path from current location
                const basePath = window.location.pathname.replace('/jsonld-network', '');
                // Open JSON files in the viewer in a new tab
                window.open(`${basePath}/jsonld-viewer?url=${encodeURIComponent(url)}`, '_blank');
            } else {
                // Open other files in a new tab
                window.open(url, '_blank');
            }
        }

        function getUrlType(url) {
            const ext = url.split('.').pop().toLowerCase();
            return ext === 'json' ? 'json' : 'other';
        }

        async function fetchAndProcessJson(url) {
            try {
                const response = await fetch(url, {
                    mode: 'cors',
                    headers: {
                        'Accept': 'application/json, text/plain, */*'
                    }
                });
                const contentType = response.headers.get('content-type');
                
                if (!contentType?.includes('application/json')) {
                    // 非JSON文件也添加到图中，但不继续解析
                    return { isJson: false };
                }

                const data = await response.json();
                return { isJson: true, data };
            } catch (error) {
                console.error('获取数据失败：', error);
                return { isJson: false };
            }
        }

        function getNodeShape(url) {
            const ext = url.split('.').pop().toLowerCase();
            const shapes = {
                'json': 'box',
                'yaml': 'diamond',
                'pdf': 'triangle',
                'default': 'box'
            };
            return shapes[ext] || shapes.default;
        }

        function getNodeColor(url) {
            const ext = url.split('.').pop().toLowerCase();
            const colors = {
                'json': { background: '#2563eb', border: '#1d4ed8' },  // 蓝色
                'yaml': { background: '#059669', border: '#047857' },  // 绿色
                'jpg': { background: '#7c3aed', border: '#6d28d9' },   // 紫色
                'jpeg': { background: '#7c3aed', border: '#6d28d9' },  // 紫色
                'png': { background: '#7c3aed', border: '#6d28d9' },   // 紫色
                'gif': { background: '#7c3aed', border: '#6d28d9' },   // 紫色
                'pdf': { background: '#dc2626', border: '#b91c1c' },   // 红色
                'default': { background: '#6b7280', border: '#4b5563' } // 灰色
            };
            return colors[ext] || colors.default;
        }

        function extractLinks(data) {
            const links = new Set();
            
            function traverse(obj) {
                if (!obj || typeof obj !== 'object') return;
                
                // 处理数组
                if (Array.isArray(obj)) {
                    obj.forEach(item => traverse(item));
                    return;
                }
                
                // 处理对象
                for (const [key, value] of Object.entries(obj)) {
                    // 跳过@context和owner中的链接
                    if (key === '@context' || (key === '@id' && obj['@type'] === 'Organization')) {
                        continue;
                    }
                    
                    // 处理@id和url字段
                    if ((key === '@id' || key === 'url') && typeof value === 'string' && isValidUrl(value)) {
                        links.add(value);
                    }
                    
                    // 递归处理对象
                    if (typeof value === 'object' && value !== null) {
                        traverse(value);
                    }
                }
            }
            
            traverse(data);
            return Array.from(links);
        }

        function isValidUrl(string) {
            try {
                new URL(string);
                return true;
            } catch (_) {
                return false;
            }
        }

        async function analyzeAndDrawNetwork(url, responseData, parentId = null, level = 0) {
            if (level >= MAX_LEVEL || processedUrls.has(url)) {
                return;
            }

            processedUrls.add(url);
            const nodeId = url;
            const fileName = url.split('/').pop();
            const fileExt = fileName.split('.').pop().toLowerCase();
            
            // 添加当前节点
            if (!nodes.get(nodeId)) {
                const colors = getNodeColor(url);
                nodes.add({
                    id: nodeId,
                    label: fileName,
                    url: url,
                    level: level,
                    shape: getNodeShape(url),
                    color: colors.background,
                    borderWidth: 2,
                    borderColor: colors.border,
                    font: {
                        color: '#000000',
                        background: '#ffffff'
                    }
                });
            }

            // 添加边
            if (parentId) {
                edges.add({
                    from: parentId,
                    to: nodeId,
                    arrows: {
                        to: {
                            enabled: true,
                            type: 'arrow'
                        }
                    }
                });
            }

            // 如果是JSON文件，继续解析链接
            if (responseData.isJson && responseData.data) {
                const links = extractLinks(responseData.data);
                console.log('Found links:', links); // 调试用
                for (const link of links) {
                    if (!processedUrls.has(link)) {
                        const childData = await fetchAndProcessJson(link);
                        await analyzeAndDrawNetwork(link, childData, nodeId, level + 1);
                    }
                }
            }
        }

        // 从URL参数获取初始URL并开始分析
        async function init() {
            const urlParams = new URLSearchParams(window.location.search);
            const initialUrl = urlParams.get('url');
            
            if (initialUrl) {
                const data = await fetchAndProcessJson(initialUrl);
                if (data) {
                    initNetwork();
                    await analyzeAndDrawNetwork(initialUrl, data);
                    
                    // 等待布局稳定后调整视图
                    setTimeout(() => {
                        network.fit({
                            animation: {
                                duration: 1000,
                                easingFunction: 'easeInOutQuad'
                            }
                        });
                    }, 1000);
                }
            }
        }

        // 页面加载完成后开始初始化
        document.addEventListener('DOMContentLoaded', init);
    </script>
</body>
</html>
